<template>
    <div class="map-container">
        <div :id="props.mapName"></div>
    </div>
</template>

<script setup>
import util from '../utils'
import { useMapStore } from '../store'
import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
const mapStore = useMapStore()
const map = ref(null)
const localtion = ref(null)
const layers = reactive([])
const points = reactive([])
const addLayerMessage = ref('')
const props = defineProps({
    mapName: {
        default: 'map',
    }, // 地图名称
    mapType: {
        default: 'TianDiTu.Normal',
    }, // 地图类型
    annotion: {
        default: false,
    }, // 是否标注图层
    otherMapLayer: {
        default: [],
    }, // 其他图层
    center: {
        default: [31.59, 120.29],
    }, // 中心坐标
    zoomIndex: {
        default: 12,
    }, // 缩放等级
    mapOptions: {
        default: {
            zoomControl: false,
            attributionControl: false,
            preferCanvas: true,
        },
    }, // 地图配置
    layerOptions: {
        default: {
            maxZoom: 18,
            minZoom: 5,
        },
    }, // 图层配置
    isLocation: {
        default: true,
    }, // 是否定位
    isMessage: {
        default: true,
    }, // 是否提示
})
// 地图类型
const types = {
    TianDiTu: {
        Normal: ['Map', 'Annotion'],
        Satellite: ['Map', 'Annotion'],
        Terrain: ['Map', 'Annotion'],
    },
    GaoDe: {
        Normal: ['Map'],
        Satellite: ['Map', 'Annotion'],
    },
    Google: {
        Normal: ['Map'],
        Satellite: ['Map', 'Annotion'],
    },
    Geoq: {
        Normal: ['Map', 'PurplishBlue', 'Gray', 'Warm'],
        Theme: ['Hydro'],
    },
    OSM: {
        Normal: ['Map'],
    },
    Baidu: {
        Normal: ['Map'],
        Satellite: ['Map', 'Annotion'],
    },
    Tencent: {
        Normal: ['Map'],
        Satellite: ['Map'],
        Terrain: ['Map'],
    },
}
// 定位获取后fly并标点
watch(localtion, newValue => {
    // gps84转gcj02
    const { lng, lat } = util.gps84Togcj02(newValue[1], newValue[0])
    map.value.flyTo([lat, lng], 18, { duration: 5 })
    const point = util.map.createMakerByLatlng(map.value, [lat, lng], {
        highlight: 'permanent', //永久高亮显示
    })
    points.push(point)
})
onMounted(() => {
    // 获取定位
    props.isLocation && util.getLocaltion(localtion, props.isMessage)
    // 创建地图对象
    map.value = util.map.createMap(props.mapName, props.mapOptions)
    mapStore.setMap(map.value)
    // 设置中心点和缩放
    map.value.setView(props.center, props.zoomIndex)
    // 获取图层类型
    const mapType = props.mapType.split('.')
    let type = ''
    mapType.map((item, index) => {
        index === 0 ? (type = types[item]) : (type = type[item])
    })
    if (type) {
        // 加载底图
        let layer = util.map.createLayerByChinaProvider(map.value, `${props.mapType}.${type[0]}`, {
            maxZoom: 18,
            minZoom: 5,
        })
        layers.push({ name: `${props.mapType}.${type[0]}`, layer })
        // 是否需要标注
        if (props.annotion) {
            //该地图是否有标注
            if (type.includes('Annotion')) {
                layer = util.map.createLayerByChinaProvider(
                    map.value,
                    `${props.mapType}.Annotion`,
                    props.layerOptions
                )
                layers.push({ name: `${props.mapType}.Annotion`, layer })
            } else {
                props.isMessage && util.message.error(`${props.mapType}.Annotion图层加载失败`)
            }
        }
        // 是否加载其他图层
        if (props.otherMapLayer) {
            let layerMessage = ''
            props.otherMapLayer.map(item => {
                if (type.includes(item)) {
                    layer = util.map.createLayerByChinaProvider(
                        map.value,
                        `${props.mapType}.${item}`,
                        props.layerOptions
                    )
                    layers.push({ name: `${props.mapType}.${item}`, layer })
                } else {
                    layerMessage += `,${props.mapType}.${item}`
                }
            })
            props.isMessage &&
                layerMessage &&
                util.message.error(`图层${layerMessage.slice(1)}加载失败`)
        }
        // 成功加载提示
        let layerMessage = ''
        layers.forEach(item => {
            layerMessage += `,${item.name}`
        })
        addLayerMessage.value = `成功加载${layerMessage.slice(1)}图层`
        props.isMessage && util.message.success(addLayerMessage.value)
    } else {
        // 加载默认图层
        let layer = util.map.createLayerByChinaProvider(
            map.value,
            'TianDiTu.Satellite.Map',
            props.layerOptions
        )
        layers.push({ name: 'TianDiTu.Satellite.Map', layer })
        layer = util.map.createLayerByChinaProvider(
            map.value,
            'TianDiTu.Satellite.Annotion',
            props.layerOptions
        )
        layers.push({ name: 'TianDiTu.Satellite.Annotion', layer })
        let layerMessage = ''
        layers.forEach(item => {
            layerMessage += `,${item.name}`
        })
        addLayerMessage.value = `图层加载失败，加载默认${layerMessage.slice(1)}图层`
        props.isMessage && util.message.success(addLayerMessage.value)
    }
})
onBeforeUnmount(() => {
    points.map(item => {
        item.getContainer().remove()
        item.remove()
    })
    points.splice(0, points.length)
    layers.map(item => {
        item.layer.getContainer().remove()
        item.layer.remove()
    })
    layers.splice(0, layers.length)
    map.value.remove()
})
</script>

<style scoped lang="less">
.map-container {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;

    div {
        width: 100%;
        height: 100%;
    }
}
</style>
